import 'package:flutter/material.dart';
import 'package:flutter_public/widget/text/require_text.dart';

import '../../config/public_color.dart';
import '../../foundation/style/bold_text_style.dart';
import '../../foundation/style/medium_text_style.dart';
import '../../foundation/style/normal_text_style.dart';
import '../container/separated_row.dart';
import '../image/public_arrow.dart';

/// FileName horizontal_item
///
/// @Author lax
/// @Date 2023/3/29
///
/// @Description

class HorizontalItem extends StatelessWidget {
  static TextStyle? defaultTitleStyle;

  static TextStyle? defaultValueStyle;

  static TextStyle? defaultUnableTitleStyle;

  static TextStyle? defaultUnableValueStyle;

  static TextStyle? defaultHintTextStyle;

  static EdgeInsets? defaultPadding =
      const EdgeInsets.symmetric(horizontal: 16, vertical: 16);

  static double? defaultTitleWidth;
  static double? defaultValueWidth;
  static (int, int) defaultFlex = (1, 1);

  static AxisDirection? defaultArrowDirection;

  final String? title;
  final String? value;
  final String? hintText;

  final bool enable;
  final bool required;
  final bool inkWell;

  final GestureTapCallback? onTap;

  late final EdgeInsets? padding;

  late final TextStyle? titleStyle;
  late final TextStyle? valueStyle;
  late final TextStyle? unableTitleStyle;
  late final TextStyle? unableValueStyle;
  late final TextStyle? hintTextStyle;

  /// 标题宽度 title不为null时生效
  /// 不设置则以flexRatio为准
  /// flexRatio为titleWidth与valueWidth的比例，默认为(1, 1)
  late final double? titleWidth;
  late final double? valueWidth;
  late final (int, int) flex;

  /// 箭头朝向
  late final AxisDirection? arrowDirection;

  final Widget? leftWidget;
  final Widget? rightWidget;
  final Widget? titleWidget;
  final Widget? valueWidget;
  final Widget? separator;

  final MainAxisAlignment mainAxisAlignment;
  final CrossAxisAlignment crossAxisAlignment;

  HorizontalItem({
    super.key,
    this.title,
    this.value,
    this.hintText,
    this.enable = true,
    this.required = false,
    this.inkWell = true,
    this.onTap,
    EdgeInsets? padding,
    TextStyle? titleStyle,
    TextStyle? valueStyle,
    TextStyle? unableTitleStyle,
    TextStyle? unableValueStyle,
    TextStyle? hintTextStyle,
    double? titleWidth,
    double? valueWidth,
    (int, int)? flex,
    AxisDirection? arrowDirection,
    this.leftWidget,
    this.rightWidget,
    this.titleWidget,
    this.valueWidget,
    this.separator = const SizedBox(width: 8),
    this.mainAxisAlignment = MainAxisAlignment.start,
    this.crossAxisAlignment = CrossAxisAlignment.center,
  }) {
    this.titleStyle = titleStyle ?? defaultTitleStyle ?? BoldTextStyle();
    this.valueStyle = valueStyle ?? defaultValueStyle ?? NormalTextStyle();
    this.unableTitleStyle =
        unableTitleStyle ?? defaultUnableTitleStyle ?? MediumTextStyle();
    this.unableValueStyle =
        unableValueStyle ?? defaultUnableValueStyle ?? NormalTextStyle();
    this.hintTextStyle = hintTextStyle ??
        defaultHintTextStyle ??
        TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.normal,
            color: PublicColor.hintText);
    this.padding = padding ?? defaultPadding ?? EdgeInsets.zero;
    this.titleWidth = titleWidth ?? defaultTitleWidth;
    this.valueWidth = valueWidth ?? defaultValueWidth;
    this.flex = flex ?? defaultFlex;
    this.arrowDirection = arrowDirection ?? defaultArrowDirection;
  }

  @override
  Widget build(BuildContext context) {
    if (!enable || onTap == null) {
      return body();
    }
    return inkWell
        ? InkWell(onTap: onTap, child: body())
        : GestureDetector(onTap: onTap, child: body());
  }

  Widget body() {
    List<Widget> children = [];
    Widget? widget;

    final haveTitle = titleWidget != null || title != null;
    final haveValue =
        valueWidget != null || value != null || (enable && hintText != null);

    if (haveTitle && haveValue) {
      if (titleWidget == null && titleWidth != null && haveValue) {
        children.add(SizedBox(width: titleWidth, child: _titleWidget()));
      } else {
        children.add(
            Flexible(fit: FlexFit.tight, flex: flex.$1, child: _titleWidget()));
      }
      if (titleWidth != null && valueWidth != null) {
        children.add(const Spacer());
      }
      if (valueWidget == null && valueWidth != null && haveTitle) {
        children.add(SizedBox(width: valueWidth, child: _valueWidget()));
      } else {
        children.add(
            Flexible(fit: FlexFit.tight, flex: flex.$2, child: _valueWidget()));
      }
    } else if (haveTitle && !haveValue) {
      widget = _titleWidget();
    } else if (!haveTitle && haveValue) {
      widget = _valueWidget();
    }

    return SeparatedRow(
      padding: padding,
      mainAxisAlignment: mainAxisAlignment,
      crossAxisAlignment: crossAxisAlignment,
      separator: separator,
      children: [
        Visibility(
          visible: leftWidget != null,
          child: leftWidget ?? const SizedBox(),
        ),
        Expanded(
          child: children.isNotEmpty
              ? SeparatedRow(
                  mainAxisAlignment: mainAxisAlignment,
                  crossAxisAlignment: crossAxisAlignment,
                  separator: separator,
                  children: children,
                )
              : widget ?? const SizedBox(),
        ),
        Visibility(
          visible: rightWidget != null,
          child: rightWidget ?? const SizedBox(),
        ),
        Visibility(
          visible: enable && arrowDirection != null,
          child: PublicArrow(direction: arrowDirection),
        ),
      ],
    );
  }

  Widget _titleWidget() {
    return RequireText(
      required: required,
      text: title,
      style: enable ? titleStyle : unableTitleStyle,
      textWidget: titleWidget,
    );
  }

  Widget _valueWidget() {
    return valueWidget ??
        Text(
          enable ? (value ?? hintText ?? '') : (value ?? ''),
          style: enable
              ? (value == null ? hintTextStyle : valueStyle)
              : unableValueStyle,
          textAlign: TextAlign.right,
        );
  }
}
